package com.terra.ns.imp.common.satoken.custom

import cn.dev33.satoken.dao.SaTokenDao
import cn.dev33.satoken.util.SaFoxUtil
import com.terra.ns.imp.common.redis.utils.RedisUtils
import java.time.Duration

/**
@author qins
@date 2023/6/1
@desc 使用自定义的redisson客户端存储和获取satoken信息
 */
class RedissonTokenDao : SaTokenDao {

    /**
     * 获取Value，如无返空
     */
    override fun get(key: String): String? {
        return RedisUtils.get(key)
    }

    /**
     * 写入Value，并设定存活时间 (单位: 秒)
     * @param key 键名称
     * @param value  值
     * @param  timeout 过期时间(值大于0时限时存储，值=-1时永久存储，值=0或小于-2时不存储)
     */
    override fun set(key: String, value: String, timeout: Long) {
        if (timeout == 0L || timeout <= SaTokenDao.NOT_VALUE_EXPIRE) {
            return
        }
        // 判断是否为永不过期
        if (timeout == SaTokenDao.NEVER_EXPIRE) {
            RedisUtils.set(key, value)
        } else {
            RedisUtils.set(key, value, Duration.ofSeconds(timeout))
        }
    }

    /**
     * 更新Value (过期时间不变)
     */
    override fun update(key: String, value: String) {
        val expire = getTimeout(key)
        if (expire == SaTokenDao.NOT_VALUE_EXPIRE) {
            return
        }
        set(key, value, expire)
    }

    /**
     * 删除Value
     */
    override fun delete(key: String) {
        RedisUtils.delete(key)
    }

    /**
     * 获取Value的剩余存活时间 (单位: 秒)
     */
    override fun getTimeout(key: String): Long {
        val timeout = RedisUtils.getTimeToLive(key)
        return if (timeout < 0) timeout else timeout / 1000
    }

    /**
     * 修改Value的剩余存活时间 (单位: 秒)
     */
    override fun updateTimeout(key: String, timeout: Long) {
        // 判断是否想要设置为永久
        if (timeout == SaTokenDao.NEVER_EXPIRE) {
            val expire = getTimeout(key)
            if (expire != SaTokenDao.NEVER_EXPIRE) {
                // 如果尚未被设置为永久，那么再次set一次
                set(key, get(key)!!, timeout)
                return
            }
        }
        RedisUtils.expire(key, Duration.ofSeconds(timeout))
    }

    /**
     * 获取Object，如无返空
     */
    override fun getObject(key: String): Any? {
        return RedisUtils.get(key);
    }

    /**
     * 写入Object，并设定存活时间 (单位: 秒)
     */
    override fun setObject(key: String, value: Any, timeout: Long) {
        if (timeout == 0L || timeout <= SaTokenDao.NOT_VALUE_EXPIRE) {
            return
        }
        // 判断是否为永不过期
        if (timeout == SaTokenDao.NEVER_EXPIRE) {
            RedisUtils.set(key, value)
        } else {
            RedisUtils.set(key, value, Duration.ofSeconds(timeout))
        }
    }

    /**
     * 更新Object (过期时间不变)
     */
    override fun updateObject(key: String, value: Any) {
        val expire = getTimeout(key)
        if (expire == SaTokenDao.NOT_VALUE_EXPIRE) {
            return
        }
        setObject(key, value, expire)
    }

    /**
     * 删除Object
     */
    override fun deleteObject(key: String) {
        RedisUtils.delete(key)
    }

    override fun getObjectTimeout(key: String): Long {
        val timeout = RedisUtils.getTimeToLive(key)
        return if (timeout < 0) timeout else timeout / 1000
    }

    override fun updateObjectTimeout(key: String, timeout: Long) {
        // 判断是否想要设置为永久
        if (timeout == SaTokenDao.NEVER_EXPIRE) {
            val expire = getTimeout(key)
            if (expire != SaTokenDao.NEVER_EXPIRE) {
                // 如果尚未被设置为永久，那么再次set一次
                set(key, get(key)!!, timeout)
                return
            }
        }
        RedisUtils.expire(key, Duration.ofSeconds(timeout))
    }

    override fun searchData(
        prefix: String,
        keyword: String,
        start: Int,
        size: Int,
        sortType: Boolean
    ): MutableList<String> {
        val keys: Collection<String> = RedisUtils.keys("$prefix*$keyword*")
        val list: List<String> = ArrayList(keys)
        return SaFoxUtil.searchList(list, start, size, sortType)
    }
}